// eeprom layout:
//    IR code 1 (decode_results + RAWBUF) 
//    IR code 2 (decode_results + RAWBUF) 
//    IR code 3 (decode_results + RAWBUF) 
//    IR code 4 (decode_results + RAWBUF) 
//    IR code 5 (decode_results + RAWBUF) 
//    IR code 6 (decode_results + RAWBUF) 
//    Pan range (int + int)
//    Tilt range (int + int)

// arduino uno has 1kb or EEPROM


void read_ir_code_from_eeprom(int action, decode_results *results) {
  int i;
  byte *dp;
  int eep;
  volatile unsigned int *bufp;

  eep = eeprom_location(action);

  dp = (byte *) &(results -> decode_type);
  for (i = 0; i < sizeof(results -> decode_type); i++)
    *dp++ = EEPROM.read(eep++);

  dp = (byte *) &(results -> command);
  for (i = 0; i < sizeof(results -> command); i++)
    *dp++ = EEPROM.read(eep++);

  dp = (byte *) &(results -> value);
  for (i = 0; i < sizeof(results -> value); i++)
    *dp++ = EEPROM.read(eep++);

  dp = (byte *) &(results -> bits);
  for (i = 0; i < sizeof(results -> bits); i++)
    *dp++ = EEPROM.read(eep++);

  bufp = results -> rawbuf;
  for (i = 0; i < RAWBUF; i++)
    *bufp++ = (volatile unsigned int) EEPROM.read(eep++);

  dp = (byte *) &(results -> rawlen);
  for (i = 0; i < sizeof(results -> rawlen); i++)
    *dp++ = EEPROM.read(eep++);

}
  
int write_ir_code_to_eeprom(int action, decode_results *results) {
  int i;
  byte *dp;
  int eep;
  volatile unsigned int *bufp;

  eep = eeprom_location(action);

  dp = (byte *) &(results -> decode_type);
  for (i = 0; i < sizeof(results -> decode_type); i++)
    EEPROM.write(eep++, *dp++);

  dp = (byte *) &(results -> command);
  for (i = 0; i < sizeof(results -> command); i++)
    EEPROM.write(eep++, *dp++);

  dp = (byte *) &(results -> value);
  for (i = 0; i < sizeof(results -> value); i++)
    EEPROM.write(eep++, *dp++);

  dp = (byte *) &(results -> bits);
  for (i = 0; i < sizeof(results -> bits); i++)
    EEPROM.write(eep++, *dp++);

  bufp = results -> rawbuf;
  for (i = 0; i < RAWBUF; i++)
    EEPROM.write(eep++, lowByte(*bufp++));

  dp = (byte *) &(results -> rawlen);
  for (i = 0; i < sizeof(results -> rawlen); i++)
    EEPROM.write(eep++, *dp++);

}

void read_range_from_eeprom(int command, int *minpos, int *maxpos, int *defaultpos) {
  int eep;
  
  eep = eeprom_location(7);
  
  if (command == 't') {
    eep += 6;
  } else if (command == 'z') {
    eep += 12;
  }
  
  *minpos = EEPROM.read(eep++);
  *minpos = (*minpos << 8) + EEPROM.read(eep++);

  *maxpos = EEPROM.read(eep++);
  *maxpos = (*maxpos << 8) + EEPROM.read(eep++);

  *defaultpos = EEPROM.read(eep++);
  *defaultpos = (*defaultpos << 8) + EEPROM.read(eep++);
}

void write_range_to_eeprom(char command, char ref, int pos) {
  int eep;
  
  eep = eeprom_location(7);
  
  if (command == 't') {
    eep += 6;
  } else if (command == 'z') {
    eep+= 12;
  }
  if (ref == '<') {
    eep += 2;
  } else if (ref == '@') {
    eep += 4;
  }

  EEPROM.write(eep++, pos >> 8);
  EEPROM.write(eep++, pos);

}

int eeprom_location(int action) {

  int stored_data_length = sizeof(decode_results) - sizeof(volatile unsigned int *) + RAWBUF;

  return (action - 1) * stored_data_length;

}

void dump_ir_code(int action) {

  decode_results eeprom_ir_code;
  volatile unsigned int eeprom_ir_code_rawbuf[RAWBUF];
  eeprom_ir_code.rawbuf = &eeprom_ir_code_rawbuf[0]; 
  
  Serial.print(action);
  Serial.print(": ");

  read_ir_code_from_eeprom(action, &eeprom_ir_code);
  dump(&eeprom_ir_code);
}
